package bsh.meta;

import java.util.Collection;

import org.objectweb.asm.Type;

/**
 * @author takeshi
 */
public abstract class AbstractTypeWrapper implements TypeWrapper {

    /**
     * {@inheritDoc}
     */
    public boolean isInnerClass() {
        return this.getEnclosingType() != null;
    }

    /**
     * {@inheritDoc}
     */
    public String internalName() {
        return this.className().replace('.', '/');
    }

    /**
     * {@inheritDoc}
     */
    public String typeDescription() {
        return "L" + this.className() + ";";
    }

    /**
     * {@inheritDoc}
     */
    public Type toASMType() {
        return Type.getType(this.typeDescription());
    }

    /**
     * {@inheritDoc}
     */
    public String simpleName() {
        return this.className().substring(this.className().lastIndexOf('.') + 1);
    }

    /**
     * {@inheritDoc}
     */
    public FieldDescriptor getField(String name) {
        Collection<? extends FieldDescriptor> fields = this.visibleFields();
        for (FieldDescriptor fieldDescriptor : fields) {
            if (fieldDescriptor.fieldName().equals(name)) {
                return fieldDescriptor;
            }
        }
        return null;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isSuperTypeOf(TypeWrapper another) {
        if (this.equals(another)) {
            return true;
        }
        Collection<? extends TypeWrapper> interfaces = another.interfaces();
        for (TypeWrapper typeWrapper : interfaces) {
            if (this.equals(typeWrapper)) {
                return true;
            }
        }
        TypeWrapper superType = another.superType();
        if (superType != null) {
            return this.isSuperTypeOf(superType);
        }
        return false;

    }

    /**
     * {@inheritDoc}
     */
    public boolean isPrimitive() {
        return false;
    }

    /**
     * {@inheritDoc}
     */
    public int numberOfSlots() {
        return 1;
    }

    /**
     * {@inheritDoc}
     */
    public boolean isStatic() {
        return true;
    }
}
